#include "threadPool.h"

#define WORD_LEN_MAX 20
void *threadFunc(void *pargs)
{
    // 子线程相关的函数
    threadPool_t *pthreadPool = (threadPool_t *)pargs;
    // 执行具体业务
    usraddr usr;
    int outerBreak = 0;
    while (1)
    {
        // 取出任务
        int netfd;
        // tail -f /var/log/syslog 实时查看syslog
        pthread_mutex_lock(&pthreadPool->taskQueue.mutex);
        // pthread_cleanup_push(cleanMutex,pthreadPool);
        if (pthreadPool->isexit == 1)
        {
            printf("I am going to exit!\n");
            log_INFO("I am going to exit!");
            pthread_mutex_unlock(&pthreadPool->taskQueue.mutex);
            pthread_exit(NULL);
        }

        while (pthreadPool->taskQueue.queueSize == 0)
        {
            pthread_cond_wait(&pthreadPool->taskQueue.cond, &pthreadPool->taskQueue.mutex);
            if (pthreadPool->isexit == 1)
            {
                printf("I am going to exit!\n");
                log_INFO("I am going to exit!");
                pthread_mutex_unlock(&pthreadPool->taskQueue.mutex);
                pthread_exit(NULL);
            }
        }
        printf("child thread got task!\n");
        log_INFO("child thread got task!");
        netfd = pthreadPool->taskQueue.pFront->netfd; // 把队首的数据域取出来
        taskDeQueue(&pthreadPool->taskQueue);
        pthread_mutex_unlock(&pthreadPool->taskQueue.mutex);
        // pthread_cleanup_pop(1);

        // 输入用户名，密码

        while (1)
        {
            int regFlag = 0;
            int ret = recv(netfd, &regFlag, sizeof(int), 0);

            // 接收验证结果，根据验证结果来决定是否要继续登录
            // 根据结果来判断是注册还是登录
            if (ret == 0)
            {
                outerBreak = 1;
                break;
            }
            if (regFlag == 0)
            {
                // 接收用户名
                memset(&usr, 0, sizeof(usr));
                recv(netfd, &usr.dataLen, sizeof(int), 0);
                recvn(netfd, usr.usrAddr, usr.dataLen);
                // 得到盐值
                int ret = getSalt(&usr);
                // 发送盐值
                usr.dataLen = strlen(usr.pwd);
                send(netfd, &usr.dataLen, sizeof(int), 0);
                sendn(netfd, usr.pwd, usr.dataLen);
                // 接受密文
                memset(usr.pwd, 0, sizeof(usr.pwd));
                recv(netfd, &usr.dataLen, sizeof(int), 0);
                recvn(netfd, usr.pwd, usr.dataLen);
                if (checkUsr(usr) == 0)
                {
                    // 告诉客户端继续
                    usr.flag = 0;
                    send(netfd, &usr.flag, sizeof(int), 0);
                    break;
                }
                else
                {
                    usr.flag = 1;
                    send(netfd, &usr.flag, sizeof(int), 0);
                }
            }
            else if (regFlag == 1)
            {
                selectUsr();
                memset(&usr, 0, sizeof(usr));
                recv(netfd, &usr.dataLen, sizeof(int), 0);
                recvn(netfd, usr.usrAddr, usr.dataLen);
                // 接受密码
                recv(netfd, &usr.dataLen, sizeof(int), 0);
                recvn(netfd, usr.pwd, usr.dataLen);
                if(1==usrExist(usr)){
                    int regDone = 0;
                    send(netfd, &regDone, sizeof(regDone), 0);
                    selectUsr();
                }else
                {
                    usrReg(usr);
                    fileReg(usr);
                    int regDone = 1;
                    send(netfd, &regDone, sizeof(regDone), 0);
                    selectUsr();
                }
                
            }
        }
        if (outerBreak == 1)
        {
            break;
        }
        printf("验证通过!\n");
        log_INFO("验证通过");

        // 接受信息

        pthreadPool->netfd = netfd;
        int bufLen = 0;
        int recvRet;
        fileTrain file={0};
        
        //  执行任务
        // chdir("../serverFolder");
        while (1)
        {
            bzero(pthreadPool->buf, sizeof(pthreadPool->buf));
            recvRet = recv(netfd, &bufLen, sizeof(int), 0); // 收到客户端的火车头
            if (bufLen == 0 || recvRet == 0)
            {
                printf("client exit !\n");
                log_INFO("client exit !");
                outerBreak=1;
                break;
            }
            recvn(netfd, pthreadPool->buf, bufLen); // 收火车车厢
            int count, i;
            char **words = split_words(pthreadPool->buf, &count);
            // 处理命令
            //初始化 file
            if (2 == count)
            {
                strcpy(pthreadPool->buf, words[1]);
                if (strcmp(words[0], "cd") == 0)
                {
                    if(-1==myChdir(pthreadPool));
                }
                else if (strcmp(words[0], "gets") == 0)
                {
                    printf("start transFile\n");
                    transFile(netfd, pthreadPool->buf);
                    printf("transFile finished\n");
                }
                else if (strcmp(words[0], "puts") == 0)
                {
                    chdir("../serverFolder");
                    //接受MD5
                    
                    strcpy(file.usr,usr.usrAddr);
                    strcpy(file.filename,words[1]);
                    strcpy(file.type, "f");
                    recv(netfd, &file.dataLen, sizeof(int), 0);
                    recvn(netfd, file.MD5, file.dataLen);
                    int fExist=0;
                    puts(file.MD5);
                    //检查文件目录中是否已经有该MD5的文件
                    file.parent=getUsrid(file);
                    // printFileTrain(file);
                    // printf("%d\n",file.parent);
                    if (-1 == open(file.MD5, O_RDONLY)) // 文件不存在
                    {
                        
                        send(netfd, &fExist, sizeof(int), 0);
                        // 文件的接受
                        printf("start recvFile\n");
                        recvFile(netfd);
                        printf("recvFile finished\n");
                        InsertFile(file);
                        selectFolder(file.usr);
                        int ret = rename(words[1], file.MD5);
                        ERROR_CHECK(ret, -1, "rename");
                        
                     }
                     else // 文件已存在
                     {
                         //将文件信息写入数据库
                        InsertFile(file);
                        printf("file already exist\n");
                        InsertFile(file);
                        selectFolder(file.usr);
                        fExist = 1;
                        send(netfd, &fExist, sizeof(int), 0);
                     }
                }
                else if (strcmp(words[0], "ls") == 0)
                {
                    ls(pthreadPool);
                }
                else if (strcmp(words[0], "remove") == 0)
                {
                    reMove(pthreadPool);
                }
                else
                {
                    printf("Invalid command received from client.\n");
                    log_ERROR("Invalid command received from client.");
                }
            }
            else if (1 == count)
            {
                if (strcmp(words[0], "pwd") == 0)
                {
                    pwd(pthreadPool);
                }
                else
                {
                    log_ERROR("Invalid command received from client.");
                }
            }
            // 释放空间
            for (i = 0; i < count; i++)
            {
                free(words[i]);
            }
            free(words);
        }
        // transFile(netfd);
        close(netfd);
        // 恢复空闲
        if (outerBreak == 1)
        {
            break;
        }
    }
    printf("child thread finished task!\n");
    log_INFO("child thread finished task!");
}